// #pragma once
// //hpp是开源
// #include<iostream>
// #include<string>
// #include<cassert>
// #include<functional>
// #include<pthread.h>

// //声明
// class Thread;

// struct Context
// {
//     Thread* _this;
//     void* _argc;
//     Context():_this(nullptr),_argc(nullptr)
//     { }
//     ~Context()
//     {
//     }
// };

// //template<typename T>

// class Thread
// {
// public:
//     //using func_t = std::function<void*(void*)>;
//     //using是一个关键字，用于引入命名空间、类型别名或特定成员函数等，以便在当前作用域中可以直接使用这些名称。
//     //使用using声明可以简化代码，减少冗余的限定符和命名空间前缀，提高代码的可读性和可维护性。例如：
//     // using std::cout; // 引入std命名空间中的cout标识符
//     // using namespace std; // 引入整个std命名空间
//     // using mynamespace::myFunction; // 引入mynamespace命名空间中的myFunction函数
//     typedef std::function<void*(void*)> func_t;
//     //typedef void*(*func_t)(void*);

//     const int numsize = 1024;
// public: 

// //因为成员函数会默认隐藏一个参数，所以需要函数应该设置为静态成员函数。
// static void* start_routine(void* args)
// {
//     //return _func(_args);
//     //静态成员函数内部不能访问普通成员。
//     //主要原因是因为没有this指针

//     //怎么办，把他作为参数传进来就行啦。

//     Context* ct = static_cast<Context*>(args);
//     void* ret =ct->_this->run();
//     delete ct;
//     return ret;
//     //return ct->_this->_func(ct->_this->_argc);
//     //如果把_func和_argc公有，也可以直接调用。
// }

// //执行函数必须给出，但是函数的参数可以默认为nullptr，不传入参数。
//     Thread(func_t func, int number, void* args = nullptr):_func(func), _argc(args)
//     {
//         //给线程起一个名字。
//         char buf[numsize];
//         snprintf(buf, sizeof buf, "thread-%d", number);
//         _name = buf;

//         // //或者 使用 to_string()
//         // _name = "thread-";
//         // _name += std::to_string(number);

//         //创建一个线程。
//         Context* ct = new Context();
//         ct->_argc = _argc;
//         ct->_this = this;
//         int ret =pthread_create(&_tid, nullptr, start_routine , ct); 
//         //int ret =pthread_create(&_tid, nullptr, _func, _args);
//         // pthread_create是一个语言接口，提供的都是c语言的参数类型，但是_func是c++的类对象。所以调用出问题了。
//         //typedef 设置func类型的时候使用 c++的 语法，但是pthread_create使用的c式接口。
//         //这就是c/c++混编的时候会出现的问题。
//         //可以使用 函数指针去typedef，
//         //typedef void*(*func_t)(void*);
//         assert(0 == ret);
//         (void)ret;
//     }

//     void join()
//     {

//         int ret = pthread_join(_tid, nullptr);
//         assert(0 == ret);
//         (void)ret;
//     }
//     std::string& getname()
//     {
//         return _name;
//     }

// private:
//     void* run()
//     {
//         return _func(_argc);
//     }
//     std::string _name;
//     pthread_t _tid;
//     func_t _func;
//     void* _argc; 
// };

#pragma once
//hpp是开源
#include<iostream>
#include<string>
#include<cassert>
#include<functional>
#include<pthread.h>



template<typename T>
class Thread
{
public:
    typedef void*(*func_t)(T*);
    const int numsize = 1024;
    typedef void*(*func_p)(void*);
public: 
    //执行函数必须给出，但是函数的参数可以默认为nullptr，不传入参数。
    Thread(func_t func, int number, T* args = nullptr):_func(nullptr), _argc(nullptr)
    {
        _func = (func_p)func;
        _argc = (T*)(void*)args;
        //给线程起一个名字。
        char buf[numsize];
        snprintf(buf, sizeof buf, "thread-%d", number);
        _name = buf;

        //创建一个线程。
        int ret =pthread_create(&_tid, nullptr, _func, _argc);
        assert(0 == ret);
        (void)ret;
    }

    void join()
    {
        int ret = pthread_join(_tid, nullptr);
        assert(0 == ret);
        (void)ret;
    }
    std::string _name;
    pthread_t _tid;
    func_p _func;
    void* _argc; 
};

